package com.opensource.svgaplayer.entities;

import com.opensource.svgaplayer.proto.ShapeEntity;
import com.opensource.svgaplayer.proto.Transform;
import com.opensource.svgaplayer.utils.Intrinsics;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.Matrix;
import ohos.agp.utils.RectFloat;
import ohos.agp.utils.TextTool;
import ohos.utils.zson.ZSONArray;
import ohos.utils.zson.ZSONException;
import ohos.utils.zson.ZSONObject;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * ex.
 *
 * @author wl
 * @since 2021-06-28
 */
public class SVGAVideoShapeEntity {
    private Type type;
    private Map<String, Object> args;
    private Styles styles;
    private Matrix transform;
    private Path shapePath;
    private Path sharedPath2 = new Path();

    public enum Type {
        shape,
        rect,
        ellipse,
        keep
    }

    /**
     * SVGAVideoShapeEntity
     *
     * @param obj ZSONObject
     */
    public SVGAVideoShapeEntity(ZSONObject obj) {
        this.type = Type.shape;
        this.parseType(obj);
        this.parseArgs(obj);
        this.parseStyles(obj);
        this.parseTransform(obj);
    }

    /**
     * SVGAVideoShapeEntity
     *
     * @param obj ShapeEntity
     */
    public SVGAVideoShapeEntity(ShapeEntity obj) {
        Intrinsics.checkParameterIsNotNull(obj, "obj");
        this.type = Type.shape;
        this.parseType(obj);
        this.parseArgs(obj);
        this.parseStyles(obj);
        this.parseTransform(obj);
    }

    private void parseTransform(ZSONObject obj) {
        ZSONObject transformObj = obj.getZSONObject("transform");
        if (transformObj != null) {
            Matrix transform = new Matrix();
            float[] arr = new float[9];
            double a = transformObj.getDouble("a") == null ? 1.0D : transformObj.getDoubleValue("a");
            double b = transformObj.getDoubleValue("b");
            double c = transformObj.getDoubleValue("c");
            double d = transformObj.getDouble("d") == null ? 1.0D : transformObj.getDoubleValue("d");
            double tx = transformObj.getDoubleValue("tx");
            double ty = transformObj.getDoubleValue("ty");
            arr[0] = (float) a;
            arr[1] = (float) c;
            arr[2] = (float) tx;
            arr[3] = (float) b;
            arr[4] = (float) d;
            arr[5] = (float) ty;
            arr[6] = (float) 0.0;
            arr[7] = (float) 0.0;
            arr[8] = (float) 1.0;
            transform.setElements(arr);
            this.transform = transform;
        }
    }

    private void parseTransform(ShapeEntity obj) {
        Transform transformObj = obj.transform;
        if (transformObj != null) {
            Matrix transform = new Matrix();
            float[] arr = new float[9];
            arr[0] = transformObj.a;
            arr[1] = transformObj.c;
            arr[2] = transformObj.tx;
            arr[3] = transformObj.b;
            arr[4] = transformObj.d;
            arr[5] = transformObj.ty;
            arr[6] = 0.0f;
            arr[7] = 0.0f;
            arr[8] = 1.0f;
            transform.setElements(arr);
            this.transform = transform;
        }
    }

    private void parseStyles(ZSONObject obj) {
        ZSONObject styles1 = obj.getZSONObject("styles");
        if (styles1 != null) {
            Styles styles = new Styles();
            ZSONArray optJSONArray = styles1.getZSONArray("fill");
            if (optJSONArray != null) {
                if (optJSONArray.size() == 4) {
                    float mulValue = this.checkValueRange(optJSONArray);
                    styles.setFill(Color.argb((int) (optJSONArray.getDoubleValue(3) * mulValue),
                            (int) (optJSONArray.getDoubleValue(0) * mulValue),
                            (int) (optJSONArray.getDoubleValue(1) * mulValue),
                            (int) (optJSONArray.getDoubleValue(2) * mulValue)));
                }
            }
            ZSONArray stroke = styles1.getZSONArray("stroke");
            if (stroke != null) {
                if (stroke.size() == 4) {
                    float mulValue = this.checkValueRange(stroke);
                    styles.setStroke(Color.argb((int) (stroke.getDoubleValue(3) * mulValue),
                            (int) (stroke.getDoubleValue(0) * mulValue),
                            (int) (stroke.getDoubleValue(1) * mulValue),
                            (int) (stroke.getDoubleValue(2) * mulValue)));
                }
            }
            styles.setStrokeWidth((float) (styles1.getDoubleValue("strokeWidth")));
            String lineCap = TextTool.isNullOrEmpty(styles1.getString("lineCap")) ? "butt" : styles1.getString("lineCap");
            styles.setLineCap(lineCap);
            String lineJoin = TextTool.isNullOrEmpty(styles1.getString("lineJoin")) ? "miter" : styles1.getString("lineJoin");
            styles.setLineJoin(lineJoin);
            styles.setMiterLimit(styles1.getIntValue("miterLimit"));
            ZSONArray lineDash = styles1.getZSONArray("lineDash");
            if (lineDash != null) {
                float[] floats = new float[lineDash.size()];

                for (int i = 0; i < lineDash.size(); i++) {
                    floats[i] = (float) (lineDash.getDoubleValue(i));
                }
                styles.setLineDash(floats);
            }
            this.styles = styles;
        }
    }

    private float checkValueRange(ZSONArray obj) {
        if (obj.getDouble(3) <= 1 &&
                obj.getDouble(0) <= 1 &&
                obj.getDouble(1) <= 1 &&
                obj.getDouble(2) <= 1
        ) {
            return 255f;
        } else {
            return 1f;
        }
    }

    private void parseStyles(ShapeEntity obj) {
        if (obj == null || obj.styles == null) {
            return;
        }
        ShapeEntity.ShapeStyle.RGBAColor fill = obj.styles.fill;
        Styles styles1 = new Styles();
        if (fill != null) {
            float mulValue = checkValueRange(fill);
            styles1.setFill(Color.argb(
                    (int) (fill.a * mulValue),
                    (int) (fill.r * mulValue),
                    (int) (fill.g * mulValue),
                    (int) (fill.b * mulValue)));
        }
        ShapeEntity.ShapeStyle.RGBAColor stroke = obj.styles.stroke;
        if (stroke != null) {
            float mulValue = checkValueRange(stroke);
            styles1.setStroke(Color.argb(
                    (int) (stroke.a * mulValue),
                    (int) (stroke.r * mulValue),
                    (int) (stroke.g * mulValue),
                    (int) (stroke.b * mulValue)));
        }
        styles1.strokeWidth = styles == null ? 0.0f : styles.strokeWidth;
        ShapeEntity.ShapeStyle.LineCap lineCap = obj.styles.lineCap;
        if (lineCap != null) {
            switch (lineCap) {
                case LineCap_BUTT:
                    styles1.setLineCap("butt");
                    break;
                case LineCap_ROUND:
                    styles1.setLineCap("round");
                    break;
                case LineCap_SQUARE:
                    styles1.setLineCap("square");
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + lineCap);
            }
        }
        ShapeEntity.ShapeStyle.LineJoin lineJoin = obj.styles.lineJoin;
        if (lineJoin != null) {
            switch (lineJoin) {
                case LineJoin_BEVEL:
                    styles1.setLineJoin("bevel");
                    break;
                case LineJoin_MITER:
                    styles1.setLineJoin("miter");
                    break;
                case LineJoin_ROUND:
                    styles1.setLineJoin("round");
                    break;

            }
        }
        styles1.setMiterLimit((int) obj.styles.miterLimit);
        float[] floats = new float[3];
        floats[0] = obj.styles.lineDashI;
        floats[1] = obj.styles.lineDashII;
        floats[2] = obj.styles.lineDashIII;
        styles1.setLineDash(floats);
        this.styles = styles1;
    }

    private float checkValueRange(ShapeEntity.ShapeStyle.RGBAColor color) {
        float a = color.a;
        float r = color.r;
        float g = color.g;
        float b = color.b;
        if (a <= 1 &&
                r <= 1 &&
                g <= 1 &&
                b <= 1) {
            return 255f;
        } else {
            return 1f;
        }
    }

    private void parseArgs(ShapeEntity obj) {
        HashMap args = new HashMap();
        ShapeEntity.ShapeArgs shape = obj.shape;
        if (shape != null) {
            String d = shape.d;
            if (d != null) {
                args.put("d", d);
            }
        }
        ShapeEntity.EllipseArgs ellipseArgs = obj.ellipse;
        if (ellipseArgs != null) {
            args.put("x", ellipseArgs.x);
            args.put("y", ellipseArgs.y);
            args.put("radiusX", ellipseArgs.radiusX);
            args.put("radiusY", ellipseArgs.radiusY);
        }
        ShapeEntity.RectArgs rectArgs = obj.rect;
        if (rectArgs != null) {
            args.put("x", rectArgs.x);
            args.put("y", rectArgs.y);
            args.put("width", rectArgs.width);
            args.put("height", rectArgs.height);
            args.put("cornerRadius", rectArgs.cornerRadius);
        }
        this.args = args;
    }

    private void parseArgs(ZSONObject obj) {
        HashMap args = new HashMap();
        ZSONObject object = obj.getZSONObject("args");
        if (object != null) {
            Iterator iterator = object.keySet().iterator();
            Intrinsics.checkExpressionValueIsNotNull(iterator, "values.keys()");
            while (iterator.hasNext()) {
                Object element = iterator.next();
                String key = (String) element;
                Object o = null;
                try {
                    o = object.get(key);
                } catch (ZSONException e) {
                    e.printStackTrace();
                }
                if (o != null) {
                    args.put(key, o);
                }
            }
            this.args = args;
        }
    }

    private void parseType(ZSONObject ZSONObject) {
        String type = ZSONObject.getString("type");
        if (type == null) {
            return;
        }
        switch (type.toLowerCase()) {
            case "shape":
                this.type = Type.shape;
                break;
            case "rect":
                this.type = Type.rect;
                break;
            case "ellipse":
                this.type = Type.ellipse;
                break;
            case "keep":
                this.type = Type.keep;
                break;
        }
    }

    private void parseType(ShapeEntity obj) {
        if (obj == null) {
            return;
        }
        if (obj.type != null) {
            switch (obj.type) {
                case SHAPE:
                    this.type = Type.shape;
                    break;
                case RECT:
                    this.type = Type.rect;
                    break;
                case ELLIPSE:
                    this.type = Type.ellipse;
                    break;
                case KEEP:
                    this.type = Type.keep;
                    break;
            }
        }
    }

    /**
     * getType
     *
     * @return Type
     */
    public Type getType() {
        return this.type;
    }

    /**
     * getArgs
     *
     * @return Map
     */
    public Map getArgs() {
        return this.args;
    }

    /**
     * getStyles
     *
     * @return Styles
     */
    public Styles getStyles() {
        return this.styles;
    }

    /**
     * getTransform
     *
     * @return Matrix
     */
    public Matrix getTransform() {
        return this.transform;
    }

    /**
     * isKeep
     *
     * @return boolean
     */
    public boolean isKeep() {
        return this.type == Type.keep;
    }

    /**
     * getShapePath
     *
     * @return Path
     */
    public Path getShapePath() {
        return this.shapePath;
    }

    /**
     * setShapePath
     *
     * @param var1 var1
     */
    public void setShapePath(Path var1) {
        this.shapePath = var1;
    }

    public static class Styles {
        private int fill = 0x00000000;
        private int stroke = 0x00000000;
        private float strokeWidth = 0.0f;
        private String lineCap = "butt";
        private String lineJoin = "miter";
        private int miterLimit = 0;
        private float[] lineDash = new float[0];

        /**
         * getFill
         *
         * @return int
         */
        public int getFill() {
            return this.fill;
        }

        /**
         * setFill
         *
         * @param var1 var1
         */
        public void setFill(int var1) {
            this.fill = var1;
        }

        /**
         * getStroke
         *
         * @return int
         */
        public int getStroke() {
            return this.stroke;
        }

        /**
         * setStroke
         *
         * @param var1 var1
         */
        public void setStroke(int var1) {
            this.stroke = var1;
        }

        /**
         * getStrokeWidth
         *
         * @return float
         */
        public float getStrokeWidth() {
            return this.strokeWidth;
        }

        /**
         * setStrokeWidth
         *
         * @param var1 var1
         */
        public void setStrokeWidth(float var1) {
            this.strokeWidth = var1;
        }

        /**
         * getLineCap
         *
         * @return String
         */
        public String getLineCap() {
            return this.lineCap;
        }

        /**
         * setLineCap
         *
         * @param var1 var1
         */
        public void setLineCap(String var1) {
            Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
            this.lineCap = var1;
        }

        /**
         * getLineJoin
         *
         * @return String
         */
        public String getLineJoin() {
            return this.lineJoin;
        }

        /**
         * setLineJoin
         *
         * @param var1 var1
         */
        public void setLineJoin(String var1) {
            Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
            this.lineJoin = var1;
        }

        /**
         * getMiterLimit
         *
         * @return int
         */
        public int getMiterLimit() {
            return this.miterLimit;
        }

        /**
         * setMiterLimit
         *
         * @param var1 var1
         */
        public void setMiterLimit(int var1) {
            this.miterLimit = var1;
        }

        /**
         * getLineDash
         *
         * @return float[]
         */
        public float[] getLineDash() {
            return this.lineDash.clone();
        }

        /**
         * setLineDash
         *
         * @param var1 float[]
         */
        public void setLineDash(float[] var1) {
            Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
            this.lineDash = var1.clone();
        }
    }

    /**
     * buildPath
     */
    public void buildPath() {
        if (this.shapePath != null) {
            return;
        }
        sharedPath2.reset();
        if (this.type == Type.shape) {
            if (this.args != null && this.args.get("d") instanceof String) {
                new SVGAPathEntity((String) (this.args.get("d"))).buildPath(sharedPath2);
            }
        } else if (this.type == Type.ellipse) {
            float x = 0.0f;
            float y = 0.0f;
            float rx = 0.0f;
            float ry = 0.0f;
            if (args != null) {
                Object x1 = this.args.get("x");
                if (x1 instanceof Number) {
                    Number xv = (Number) x1;
                    x = xv.floatValue();
                } else {
                    return;
                }
            }
            if (args != null) {
                Object x2 = this.args.get("y");
                if (x2 instanceof Number) {
                    Number yv = (Number) x2;
                    y = yv.floatValue();
                } else {
                    return;
                }
            }
            if (args != null) {
                Object x3 = this.args.get("radiusX");
                if (x3 instanceof Number) {
                    Number rxv = (Number) x3;
                    rx = rxv.floatValue();
                } else {
                    return;
                }
            }

            if (args != null) {
                Object x4 = this.args.get("radiusY");
                if (x4 instanceof Number) {
                    Number ryv = (Number) x4;
                    ry = ryv.floatValue();
                } else {
                    return;
                }
            }
            sharedPath2.addOval(new RectFloat(
                    new BigDecimal(x).subtract(new BigDecimal(rx)).floatValue()
                    , new BigDecimal(y).subtract(new BigDecimal(ry)).floatValue()//y - ry
                    , new BigDecimal(x).add(new BigDecimal(rx)).floatValue()//x + rx
                    , new BigDecimal(y).add(new BigDecimal(ry)).floatValue()
            ), Path.Direction.CLOCK_WISE);
        } else if (this.type == Type.rect) {
            float x = 0.0f;
            float y = 0.0f;
            float width = 0.0f;
            float height = 0.0f;
            float cornerRadius = 0.0f;
            if (args != null) {
                Object y1 = this.args.get("x");
                if (y1 instanceof Number) {
                    Number xv = (Number) y1;
                    x = xv.floatValue();
                } else {
                    return;
                }
            }
            if (args != null) {
                Object y2 = this.args.get("y");
                if (y2 instanceof Number) {
                    Number xv = (Number) y2;
                    y = xv.floatValue();
                } else {
                    return;
                }
            }
            if (args != null) {
                Object y3 = this.args.get("width");
                if (y3 instanceof Number) {
                    Number xv = (Number) y3;
                    width = xv.floatValue();
                } else {
                    return;
                }
            }
            if (args != null) {
                Object y4 = this.args.get("height");
                if (y4 instanceof Number) {
                    Number xv = (Number) y4;
                    height = xv.floatValue();
                } else {
                    return;
                }
            }
            if (args != null) {
                Object y5 = this.args.get("cornerRadius");
                if (y5 instanceof Number) {
                    Number xv = (Number) y5;
                    cornerRadius = xv.floatValue();
                } else {
                    return;
                }
            }
            sharedPath2.addRoundRect(new RectFloat(x, y,
                    new BigDecimal(x).add(new BigDecimal(width)).floatValue()
                    , new BigDecimal(y).add(new BigDecimal(height)).floatValue()
            ), cornerRadius, cornerRadius, Path.Direction.CLOCK_WISE);
        }
        this.shapePath = new Path();
        this.shapePath.set(sharedPath2);
    }
}
